using System.Text.Json;

namespace SPI.AgentServer.Services.Export;

/// <summary>
/// ECharts 图表服务 - 优化版，只要有数据就生成图表
/// </summary>
public class EChartsService : IChartService
{
    private readonly ILogger<EChartsService> _logger;

    public EChartsService(ILogger<EChartsService> logger)
    {
        _logger = logger;
    }

    public async Task<ChartResult> GenerateChartAsync(object data)
    {
        return await Task.Run(() =>
        {
            try
            {
                _logger.LogInformation("开始生成图表");
                
                // 解析数据
                var (columns, rows) = ParseData(data);
                
                _logger.LogInformation("解析结果 - 列数: {ColumnCount}, 行数: {RowCount}", columns.Count, rows.Count);
                
                if (columns.Count == 0 || rows.Count == 0)
                {
                    return NoChart("无数据");
                }

                // 智能识别列
                var labelColumn = FindLabelColumn(columns);
                var valueColumn = FindValueColumn(columns);
                
                _logger.LogInformation("识别列 - 标签列: {Label}, 数值列: {Value}", labelColumn, valueColumn);
                
                if (string.IsNullOrEmpty(labelColumn) || string.IsNullOrEmpty(valueColumn))
                {
                    return NoChart("无法识别合适的列");
                }

                // 提取数据（最多50条）
                var (labels, values) = ExtractData(rows, labelColumn, valueColumn, 50);
                
                _logger.LogInformation("提取数据 - 标签数: {LabelCount}, 数值总和: {Sum}", labels.Count, values.Sum());

                if (labels.Count == 0)
                {
                    return NoChart("无有效数据");
                }

                // 生成折线图配置
                var config = GenerateLineChartConfig(labels, values, valueColumn);
                
                var configJson = JsonSerializer.Serialize(config);
                
                _logger.LogInformation("图表生成成功 - 类型: bar, 数据点: {Count}", labels.Count);
                
                return new ChartResult
                {
                    ChartType = "line",
                    Config = configJson,
                    Summary = $"生成趋势图，包含 {labels.Count} 条数据"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "图表生成失败");
                return NoChart(ex.Message);
            }
        });
    }

    /// <summary>
    /// 解析数据结构
    /// </summary>
    private (List<string> columns, List<Dictionary<string, object>> rows) ParseData(object data)
    {
        var columns = new List<string>();
        var rows = new List<Dictionary<string, object>>();

        try
        {
            var dataType = data.GetType();
            var columnsProperty = dataType.GetProperty("columns");
            var rowsProperty = dataType.GetProperty("rows");

            if (columnsProperty != null && rowsProperty != null)
            {
                var columnsValue = columnsProperty.GetValue(data);
                var rowsValue = rowsProperty.GetValue(data);

                // 提取列名
                if (columnsValue is IEnumerable<object> colEnumerable)
                {
                    columns = colEnumerable.Select(c => c?.ToString() ?? "").Where(c => !string.IsNullOrEmpty(c)).ToList();
                }

                // 提取行数据
                if (rowsValue is IEnumerable<object> rowEnumerable)
                {
                    foreach (var row in rowEnumerable)
                    {
                        var rowDict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

                        
                        // 检查是否已经是字典类型
                        if (row is IDictionary<string, object> dict)
                        {
                            foreach (var kvp in dict)
                            {
                                rowDict[kvp.Key] = kvp.Value;
                            }
                        }
                        else
                        {
                            // 如果不是字典，尝试反射获取属性
                            var rowType = row.GetType();
                            
                            // 只获取非索引器属性
                            var properties = rowType.GetProperties()
                                .Where(p => p.GetIndexParameters().Length == 0 && 
                                           !p.Name.Equals("Comparer", StringComparison.OrdinalIgnoreCase) &&
                                           !p.Name.Equals("Keys", StringComparison.OrdinalIgnoreCase) &&
                                           !p.Name.Equals("Values", StringComparison.OrdinalIgnoreCase) &&
                                           !p.Name.Equals("Count", StringComparison.OrdinalIgnoreCase))
                                .ToList();
                            
                            foreach (var prop in properties)
                            {
                                try
                                {
                                    var value = prop.GetValue(row);
                                    if (value != null)
                                    {
                                        rowDict[prop.Name] = value;
                                    }
                                }
                                catch
                                {
                                    // 忽略无法读取的属性
                                }
                            }
                        }
                        
                        if (rowDict.Count > 0)
                        {
                            rows.Add(rowDict);
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "解析数据失败");
        }

        return (columns, rows);
    }

    /// <summary>
    /// 查找标签列（车牌号、姓名等）
    /// </summary>
    private string? FindLabelColumn(List<string> columns)
    {
        // 优先级顺序
        var patterns = new[]
        {
            "车牌号",
            "车牌",
            "plate",
            "姓名",
            "name",
            "学工号",
            "员工号",
            "id"
        };

        foreach (var pattern in patterns)
        {
            var found = columns.FirstOrDefault(c => 
                c.Contains(pattern, StringComparison.OrdinalIgnoreCase));
            if (found != null)
            {
                return found;
            }
        }

        // 如果没有匹配，返回第一列
        return columns.FirstOrDefault();
    }

    /// <summary>
    /// 查找数值列（时间、次数等）
    /// </summary>
    private string? FindValueColumn(List<string> columns)
    {
        // 排除的非数值列模式
        var excludePatterns = new[]
        {
            "类型",
            "名称",
            "位置",
            "标识",
            "状态",
            "颜色",
            "时间",  // 时间字段不适合作为Y轴数值
            "日期",
            "type",
            "name",
            "location",
            "status",
            "color",
            "time",
            "date"
        };
        
        // 优先级顺序 - 明确的数值字段
        var patterns = new[]
        {
            "停留分钟",
            "停留时长",
            "在校时长",
            "分钟数",
            "小时数",
            "天数",
            "次数",
            "数量",
            "count",
            "总次数",
            "进出总次数",
            "通过次数",
            "总数",
            "sum",
            "avg",
            "活跃天数"
        };

        foreach (var pattern in patterns)
        {
            var found = columns.FirstOrDefault(c => 
                c.Contains(pattern, StringComparison.OrdinalIgnoreCase) &&
                !excludePatterns.Any(ex => c.Contains(ex, StringComparison.OrdinalIgnoreCase)));
            if (found != null)
            {
                return found;
            }
        }

        // 如果没有找到明确的数值列，尝试找第一个不在排除列表中的列（放宽限制）
        _logger.LogInformation("未找到明确的数值列，尝试使用其他列");
        
        var candidateColumn = columns.FirstOrDefault(c => 
            !excludePatterns.Any(ex => c.Contains(ex, StringComparison.OrdinalIgnoreCase)) &&
            c != columns.FirstOrDefault()); // 排除第一列（通常是标签列）
        
        if (candidateColumn != null)
        {
            _logger.LogInformation("选择候选列: {Column}", candidateColumn);
            return candidateColumn;
        }

        // 实在找不到，返回第二列（如果有的话）
        if (columns.Count >= 2)
        {
            _logger.LogInformation("使用第二列作为数值列: {Column}", columns[1]);
            return columns[1];
        }

        return null;
    }

    /// <summary>
    /// 提取图表数据
    /// </summary>
    private (List<string> labels, List<double> values) ExtractData(
        List<Dictionary<string, object>> rows,
        string labelColumn,
        string valueColumn,
        int maxCount)
    {
        var labels = new List<string>();
        var values = new List<double>();

        _logger.LogInformation("开始提取数据 - 目标列: [{Label}] vs [{Value}]", labelColumn, valueColumn);
        
        var count = 0;
        foreach (var row in rows)
        {
            if (count >= maxCount) break;

            // 调试：打印行的所有键
            if (count == 0)
            {
                _logger.LogInformation("行的键: {Keys}", string.Join(", ", row.Keys));
            }

            // 提取标签（不区分大小写）
            string label = "";
            var labelKey = row.Keys.FirstOrDefault(k => k.Equals(labelColumn, StringComparison.OrdinalIgnoreCase));
            if (labelKey != null && row.ContainsKey(labelKey))
            {
                label = row[labelKey]?.ToString()?.Trim() ?? "";
            }

            // 提取数值（不区分大小写，支持多种数据类型）
            double value = 0.0;
            var valueKey = row.Keys.FirstOrDefault(k => k.Equals(valueColumn, StringComparison.OrdinalIgnoreCase));
            if (valueKey != null && row.ContainsKey(valueKey))
            {
                var val = row[valueKey];
                if (val != null)
                {
                    // 尝试直接转换（支持 int, long, decimal, double 等）
                    try
                    {
                        value = Convert.ToDouble(val);
                        
                        // 调试日志（仅前3条）
                        if (count < 3)
                        {
                            _logger.LogInformation("  提取数值 [{Column}]: {Raw} ({Type}) -> {Value}", 
                                valueColumn, val, val.GetType().Name, value);
                        }
                    }
                    catch
                    {
                        // 如果直接转换失败，尝试字符串解析
                        var valStr = val.ToString();
                        if (!string.IsNullOrEmpty(valStr) && double.TryParse(valStr, out var num))
                        {
                            value = num;
                        }
                        else if (count < 3)
                        {
                            _logger.LogWarning("  无法转换数值 [{Column}]: {Raw} ({Type})", 
                                valueColumn, val, val.GetType().Name);
                        }
                    }
                }
            }
            else if (count < 3)
            {
                _logger.LogWarning("  未找到数值列键: {Column}, 可用键: {Keys}", 
                    valueColumn, string.Join(", ", row.Keys));
            }

            // 只添加有效数据（标签不为空，或数值不为0）
            if (!string.IsNullOrWhiteSpace(label) || value != 0)
            {
                labels.Add(label);
                values.Add(value);
                count++;
                
                if (count <= 3) // 打印前3条数据用于调试
                {
                    _logger.LogDebug("数据点 {Index}: {Label} = {Value}", count, label, value);
                }
            }
        }

        _logger.LogInformation("提取完成 - 实际提取: {Count} 条数据", count);
        
        return (labels, values);
    }

    /// <summary>
    /// 生成美观的折线图配置（面积图样式）
    /// </summary>
    private object GenerateLineChartConfig(List<string> labels, List<double> values, string valueColumnName)
    {
        // 判断单位
        string unit = "数值";
        if (valueColumnName.Contains("分钟", StringComparison.OrdinalIgnoreCase))
            unit = "分钟";
        else if (valueColumnName.Contains("小时", StringComparison.OrdinalIgnoreCase))
            unit = "小时";
        else if (valueColumnName.Contains("次数", StringComparison.OrdinalIgnoreCase))
            unit = "次";
        else if (valueColumnName.Contains("数量", StringComparison.OrdinalIgnoreCase))
            unit = "个";
        else if (valueColumnName.Contains("天数", StringComparison.OrdinalIgnoreCase))
            unit = "天";

        return new
        {
            // 标题配置 - 简洁标题
            title = new
            {
                text = "趋势图",
                left = "center",
                top = "3%",
                textStyle = new 
                { 
                    fontSize = 16,
                    fontWeight = "bold",
                    color = "#333"
                }
            },
            // 提示框配置 - 只在鼠标悬停时显示
            tooltip = new
            {
                trigger = "axis",
                axisPointer = new 
                { 
                    type = "cross",
                    crossStyle = new
                    {
                        color = "#999"
                    }
                },
                backgroundColor = "rgba(255, 255, 255, 0.95)",
                borderColor = "#5470c6",
                borderWidth = 1,
                padding = new[] { 10, 15 },
                textStyle = new 
                { 
                    color = "#333", 
                    fontSize = 14 
                },
                formatter = $"{{b}}<br/><span style='display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:#5470c6;'></span>{valueColumnName}: <b>{{c}} {unit}</b>"
            },
            // 网格配置 - 充分利用空间
            grid = new
            {
                left = "3%",
                right = "4%",
                bottom = "12%",
                top = "15%",
                containLabel = true
            },
            // X轴配置 - 类别轴
            xAxis = new
            {
                type = "category",
                data = labels.ToArray(),
                boundaryGap = false, // 折线图不留边距
                axisLabel = new
                {
                    interval = labels.Count > 20 ? (int)Math.Ceiling(labels.Count / 20.0) : 0, // 自动间隔
                    rotate = labels.Count > 15 ? 30 : 0,
                    fontSize = 11,
                    color = "#666",
                    margin = 12
                },
                axisLine = new
                {
                    lineStyle = new { color = "#e0e0e0", width = 1 }
                },
                axisTick = new
                {
                    show = true,
                    lineStyle = new { color = "#e0e0e0" }
                }
            },
            // Y轴配置 - 数值轴
            yAxis = new
            {
                type = "value",
                name = valueColumnName,
                nameTextStyle = new
                {
                    fontSize = 12,
                    color = "#666",
                    padding = new[] { 0, 0, 0, 0 }
                },
                axisLabel = new
                {
                    formatter = $"{{value}}",
                    fontSize = 11,
                    color = "#666"
                },
                axisLine = new
                {
                    show = false
                },
                axisTick = new
                {
                    show = false
                },
                splitLine = new
                {
                    lineStyle = new 
                    { 
                        color = "#f5f5f5",
                        type = "solid"
                    }
                }
            },
            // 系列配置 - 面积折线图样式
            series = new[]
            {
                new
                {
                    name = valueColumnName,
                    type = "line",
                    smooth = true, // 平滑曲线
                    symbol = "circle", // 数据点样式
                    symbolSize = 6, // 数据点大小
                    data = values.ToArray(),
                    // 线条样式
                    lineStyle = new
                    {
                        color = "#5470c6",
                        width = 2
                    },
                    // 数据点样式
                    itemStyle = new
                    {
                        color = "#5470c6",
                        borderColor = "#fff",
                        borderWidth = 2
                    },
                    // 面积填充样式
                    areaStyle = new
                    {
                        color = new
                        {
                            type = "linear",
                            x = 0,
                            y = 0,
                            x2 = 0,
                            y2 = 1,
                            colorStops = new[]
                            {
                                new { offset = 0, color = "rgba(84, 112, 198, 0.3)" },
                                new { offset = 1, color = "rgba(84, 112, 198, 0.05)" }
                            }
                        }
                    },
                    // 高亮样式
                    emphasis = new
                    {
                        focus = "series",
                        itemStyle = new
                        {
                            color = "#5470c6",
                            borderColor = "#fff",
                            borderWidth = 3,
                            shadowBlur = 10,
                            shadowColor = "rgba(84, 112, 198, 0.5)"
                        }
                    },
                    // 不显示数据标签（只在悬停时显示）
                    label = new
                    {
                        show = false
                    }
                }
            },
            // 动画配置
            animationDuration = 1500,
            animationEasing = "cubicOut"
        };
    }

    private ChartResult NoChart(string reason)
    {
        _logger.LogInformation("不生成图表: {Reason}", reason);
        return new ChartResult
        {
            ChartType = "none",
            Summary = $"未生成图表: {reason}"
        };
    }
}

